package com.atguigu.stuty.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * @Author early morning
 * @Create 2025/4/25 21:15
 * @Description:
 *  在主线程中需要执行比较耗时的操作时，但又不想阻塞主线程时，可以把这些作业交给Future对象在后台完成，
 *  当主线程将来需要时，就可以通过Future对象获得后台作业的计算结果或者执行状态。
 *
 *  一般FutureTask多用于耗时的计算，主线程可以在完成自己的任务后，再去获取结果。
 *
 *  仅在计算完成时才能检索结果；如果计算尚未完成，则阻塞 get 方法。一旦计算完成，
 *  就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取，否则会一直阻塞直到任务转入完成状态，
 *  然后会返回结果或者抛出异常。
 *
 *  只计算一次
 *  get方法放到最后
 */
class MyThread implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+ "\t" + "Runnable接口的实现类");
    }
}
class MyThread2 implements Callable<String> {

    @Override
    public String call() throws Exception {
        System.out.println("----come in call method");
        //暂停几秒钟线程
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        return "java";
    }
}
public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 函数式接口可以使用 lambda 表达式
        FutureTask futureTask = new FutureTask(new MyThread2());
        Thread t1 = new Thread(futureTask,"t1");
        t1.start();
        System.out.println(futureTask.get());

        FutureTask futureTask2 = new FutureTask(new MyThread2());
        Thread t2 = new Thread(futureTask2,"t2");
        t2.start();

        System.out.println(Thread.currentThread().getName()+"\t"+"---over task");

    }
}
